package com.huayu.languo;

import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.InjectionConfig;
import com.baomidou.mybatisplus.generator.config.*;
import com.baomidou.mybatisplus.generator.config.po.TableInfo;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;
import com.google.common.base.CaseFormat;
import com.huayu.languo.common.constant.AppConstants;
import org.apache.commons.lang3.StringUtils;

import java.text.SimpleDateFormat;
import java.util.*;


public class CodeGenerator {

    // JDBC配置 , 需手动配置
    private static final String JDBC_URL = "jdbc:mysql://localhost:3306/lxk?useUnicode=true&characterEncoding=utf8&useSSL=false&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=Asia/Shanghai&tinyInt1isBit=false&autoReconnect=true&zeroDateTimeBehavior=convertToNull";

    // 需手动配置
    private static final String JDBC_USERNAME = "root";

    // 需手动配置
    private static final String JDBC_PASSWORD = "root";

    // 需手动配置
    private static final String JDBC_DIVER_CLASS_NAME = "com.mysql.jdbc.Driver";

    // 项目在硬盘上的基础路径自动获取，不用自己配置  F:\\itsoft_lxk\\gitspace\\sb-seed-api  项目基础目录
    private static final String PROJECT_PATH = System.getProperty("user.dir");

    // java文件路径
    private static final String JAVA_PATH = "/src/main/java";

    // @author
    private static final String AUTHOR = "liu xiong kang";

    private static final String DATE = new SimpleDateFormat("yyyy-MM-dd").format(new Date());// @date

    public static void main(String[] args) {
        //直接添加新表名，不会覆盖原有生成的代码
        generator(new String[]{"qr_channel", "qr_code_list", "qr_dict_detail", "qr_dict_item", "qr_land_page", "qr_project", "qr_project_channel", "qr_sub_channel", "qr_user"});
    }

    private static void generator(String... tableNames) {
        for (String tableName : tableNames) {
            if (StringUtils.isEmpty(tableName)) {
                System.out.println("======= has a empty tableName !!! ===========");
                continue;
            }
            try {
                generatorOne(tableName);
            } catch (Exception e) {
                System.err.println(tableName + " 表代码 生成异常 ：" + e.getMessage());
            }
        }
    }

    private static void generatorOne(String tableName) {
        // 代码生成器
        AutoGenerator autoGenerator = new AutoGenerator();

        // 全局配置
        GlobalConfig gc = new GlobalConfig();
        String projectPath = PROJECT_PATH;
        gc.setOutputDir(PROJECT_PATH + JAVA_PATH);
        gc.setAuthor(AUTHOR);
        gc.setOpen(false);
        gc.setSwagger2(true);
        // gc.setEnableCache(true);// mapper.XML 生成 二级缓存
        gc.setBaseResultMap(true);// mapper.XML 生成 ResultMap
        gc.setBaseColumnList(true);// mapper.XML 生成 columList
        gc.setMapperName("%sMapper");
        gc.setXmlName("%sMapper");
        gc.setServiceName("%sService");
        gc.setServiceImplName("%sServiceImpl");
        gc.setControllerName("%sController");
        //gc.setDateType()
        //gc.setEntityName()
        //gc.setIdType()
        //gc.setFileOverride(true);
        //gc.setActiveRecord(true);
        autoGenerator.setGlobalConfig(gc);

        // 数据源配置
        DataSourceConfig dsc = new DataSourceConfig();
        dsc.setDbType(DbType.MYSQL);
        dsc.setSchemaName("public");
        dsc.setDriverName(JDBC_DIVER_CLASS_NAME);
        dsc.setUsername(JDBC_USERNAME);
        dsc.setPassword(JDBC_PASSWORD);
        dsc.setUrl(JDBC_URL);
        //dsc.setTypeConvert(new MySqlTypeConvert() {
        //
        //    // 自定义数据库表字段类型转换【可选】
        //    @Override
        //    public IColumnType processTypeConvert(GlobalConfig gc, String fieldType) {
        //        System.out.println("转换类型：" + fieldType);
        //        if (fieldType.toLowerCase().contains("date")) {
        //            return DbColumnType.DATE;
        //        }
        //        return super.processTypeConvert(gc, fieldType);
        //    }
        //});
        autoGenerator.setDataSource(dsc);


        // 包配置
        PackageConfig packageConfig = new PackageConfig();
        //packageConfig.setPathInfo();
        //packageConfig.setModuleName(scanner("模块名"));
        //packageConfig.setModuleName("com.huayu.languo");
        packageConfig.setParent(AppConstants.BASE_PACKAGE);
        packageConfig.setEntity("model.po");
        packageConfig.setController("controller.admin");
        packageConfig.setService("handler.service");
        packageConfig.setServiceImpl("handler.service.impl");
        packageConfig.setMapper("mapper");
        autoGenerator.setPackageInfo(packageConfig);

        // 自定义配置
        InjectionConfig cfg = new InjectionConfig() {

            //自定义属性注入:abc
            //在.ftl(或者是.vm)模板中，通过${cfg.abc}获取属性
            @Override
            public void initMap() {
                Map<String, Object> data = new HashMap<>();
                data.put("createTime", DATE);
                data.put("author", AUTHOR);
                data.put("pkg", AppConstants.BASE_PACKAGE.concat(".controller.admin"));
                TableInfo tableInfo = this.getConfig().getTableInfoList().get(0);
                String modelNameUpperCamel = tableInfo.getEntityName();
                String tableComment = tableInfo.getComment();
                String tableName = tableInfo.getName();
                data.put("baseRequestMapping", modelNameConvertMappingPath(modelNameUpperCamel));
                data.put("modelNameUpperCamel", modelNameUpperCamel);
                data.put("modelNameLowerCamel", CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_CAMEL, modelNameUpperCamel));
                data.put("basePackage", AppConstants.BASE_PACKAGE);
                data.put("tableComment", tableComment);
                data.put("tableName", tableName);
                this.setMap(data);
            }
        };
        List<FileOutConfig> focList = new ArrayList<>();
        focList.add(new FileOutConfig("/templates/mapper.xml.ftl") {

            @Override
            public String outputFile(TableInfo tableInfo) {
                // 自定义输入文件名称
                if (!StringUtils.isEmpty(packageConfig.getModuleName())) {
                    return projectPath + "/src/main/resources/mapper/" + packageConfig.getModuleName() + "/" + tableInfo.getEntityName() + "Mapper" + StringPool.DOT_XML;
                } else {
                    return projectPath + "/src/main/resources/mapper/" + tableInfo.getEntityName() + "Mapper" + StringPool.DOT_XML;
                }
            }
        });

        cfg.setFileOutConfigList(focList);
        autoGenerator.setCfg(cfg);

        // 配置模板
        TemplateConfig templateConfig = new TemplateConfig();
        // 配置自定义输出模板
        templateConfig.setEntity("templates/entity.java");
        templateConfig.setController("templates/controller.java");
        templateConfig.setXml(null);
        autoGenerator.setTemplate(templateConfig);

        // 策略配置
        StrategyConfig strategy = new StrategyConfig();
        //strategy.setCapitalMode(true);// 全局大写命名 ORACLE 注意
        strategy.setNaming(NamingStrategy.underline_to_camel);
        strategy.setColumnNaming(NamingStrategy.underline_to_camel);
        strategy.setEntityLombokModel(true);
        strategy.setRestControllerStyle(true);
        //生成字段注解   @TableField
        // strategy.setEntityTableFieldAnnotationEnable(true);

        //根据表前缀匹配
        //strategy.setTablePrefix(new String[] { "sp_"});
        //表名
        strategy.setInclude(tableName);
        strategy.setTablePrefix(packageConfig.getModuleName() + "_");
        strategy.setSuperEntityColumns("id");
        strategy.setControllerMappingHyphenStyle(true);
        strategy.setSuperControllerClass("com.cmb.qrcode.controller.AbstractSuperController");
        strategy.setSuperEntityClass("com.cmb.qrcode.model.po.BaseSuperPO");
        strategy.setSuperMapperClass("com.cmb.qrcode.mapper.BaseSuperMapper");
        strategy.setSuperServiceClass("com.cmb.qrcode.handler.service.BaseSuperService");
        strategy.setSuperServiceImplClass("com.cmb.qrcode.handler.service.impl.BaseSuperServiceImpl");
        autoGenerator.setStrategy(strategy);
        autoGenerator.setTemplateEngine(new FreemarkerTemplateEngine());
        autoGenerator.execute();
    }



    private static String tableNameConvertMappingPath(String tableName) {
        tableName = tableName.toLowerCase();// 兼容使用大写的表名
        return "/" + (tableName.contains("_") ? tableName.replaceAll("_", "/") : tableName);
    }

    private static String modelNameConvertMappingPath(String modelName) {
        String tableName = CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, modelName);
        return tableNameConvertMappingPath(tableName);
    }



}
